package com.ubxtech.web.handler;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.ubxtech.core.context.ContextConstants;
import com.ubxtech.core.context.ContextUtil;
import com.ubxtech.core.exception.ErrorCodeCore;
import com.ubxtech.core.exception.RRException;
import com.ubxtech.core.utils.StrPool;
import com.ubxtech.web.handler.auth.LoginAuthService;
import com.ubxtech.web.utils.WebUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * @author Victor.Xiao
 * @since 2022-01-17 10:52
 **/
@Component
@Slf4j
public class LoginHandlerInterceptor implements HandlerInterceptor {

    private LoginAuthService loginAuthService;

    public LoginHandlerInterceptor(LoginAuthService loginAuthService) {
        this.loginAuthService = loginAuthService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String traceId = IdUtil.nanoId();
        String pTraceId = WebUtil.getHeader(request, ContextConstants.P_TRACE_ID);
        String globalTraceId = WebUtil.getHeader(request,ContextConstants.TRACE_ID);
        String zoneId = WebUtil.getHeader(request, ContextConstants.HEADER_TIME_ZONE_ID);

        if (StrUtil.isBlank(pTraceId)) {
            pTraceId = IdUtil.nanoId();
        }
        if (StrUtil.isNotBlank(zoneId)) {
            if (zoneId.contains(StrPool.SPACE)) {
                //header会把加号和谐,补全一下,可以把+替换成%2B
                zoneId = zoneId.replaceAll(StrPool.SPACE, "+");
            }
            ContextUtil.set(ContextConstants.HEADER_TIME_ZONE_ID,zoneId);
        }
        MDC.put(ContextConstants.X_TRACE_ID, traceId);
        MDC.put(ContextConstants.P_TRACE_ID, pTraceId);
        //skywalking的traceId,当成全局日志的id
        String skywalkingTraceId = TraceContext.traceId();
        if (StrUtil.isNotBlank(skywalkingTraceId)) {
            globalTraceId = skywalkingTraceId;
        }
        ContextUtil.setXTraceId(traceId);
        ContextUtil.setPTraceId(pTraceId);
        if (StrUtil.isNotBlank(globalTraceId)) {
            MDC.put(ContextConstants.TRACE_ID, globalTraceId);
            ContextUtil.set(ContextConstants.TRACE_ID, globalTraceId);
        }
        boolean result = loginAuthService.auth(request, response, handler);
        MDC.put(ContextConstants.USER_ID, ContextUtil.getContextToken().getUserId() + "-" + ContextUtil.getContextToken().getUsername());
        if (!result) {
            throw new RRException(ErrorCodeCore.UNAUTHORIZED);
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        ContextUtil.remove();
        MDC.clear();
    }

}
